#include <iostream>
#include <vector>

struct B {
    int m = 42;
    const char *hello() const { return "Hello world, this is B!\n"; }
};

struct D : B {
    const char *hello() const { return "Hello world, this is D!\n"; }
};

enum class E { ONE = 1, TWO, THREE };
enum EU { ONE = 1, TWO, THREE };

int main() {
    // 1. 静态向下转换
    D d;
    B &br = d; // upcast via implicit conversion
    std::cout << "1) " << br.hello();
    D &another_d = static_cast<D &>(br); // downcast
    std::cout << "1) " << another_d.hello();

    // 2. lvalue to xvalue
    std::vector<int> v0{1, 2, 3};
    std::vector<int> v2 =
        static_cast<std::vector<int> &&>(v0); // 左值转换为右值
    std::cout << "2) 转换之后移动数据, v0.size() = " << v0.size()
              << " v2.size() = " << v2.size() << '\n';

    // 3. initializing conversion
    int n = static_cast<int>(3.14);
    std::cout << "3) 转换为 int 之后 n = " << n << '\n';
    std::vector<int> v = static_cast<std::vector<int>>(10); //
    std::cout << "3) v.size() = " << v.size() << '\n';

    // 4. 丢弃表达式的值
    static_cast<void>(v2.size()); // 求值之后丢弃值

    // 5. 转换和逆转换
    void *nv = &n;
    int *ni = static_cast<int *>(nv);
    std::cout << "4) n = " << n << " ni = " << *ni << '\n';

    // 6. array-to-pointer followed by upcast
    D a[10];
    [[maybe_unused]] B *dp = static_cast<B *>(a); //数组到指针的转换

    // 7. 作用域内的枚举转换为int
    E e = E::TWO;
    int two = static_cast<int>(e);
    std::cout << "7) enum to int = " << two << '\n';

    // 8. 枚举转换
    E e2 = static_cast<E>(two);                   // int 转换为枚举
    [[maybe_unused]] EU eu = static_cast<EU>(e2); //一个枚举转换为另一个枚举

    // 9. 指针到数的转换
    int D::*pm = &D::m;
    std::cout << "9) " << br.*static_cast<int B::*>(pm) << '\n';

    // 10. void* to any type
    void *voidp = &e;
    [[maybe_unused]] std::vector<int> *p =
        static_cast<std::vector<int> *>(voidp);
}
